package com.example.filter;

import com.example.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import com.example.utils.ThreadLocalA;

import java.io.IOException;

/**
 * 令牌校验过滤器
 */
@Slf4j
@WebFilter(urlPatterns = "/*") // 拦截所有请求
public class TokenFilter implements Filter {

    /**
     * 过滤器逻辑
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 设置CORS响应头
        response.setHeader("Access-Control-Allow-Origin", "*"); // 生产环境应配置具体域名
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, token"); // 允许的请求头
        response.setHeader("Access-Control-Expose-Headers", "*"); // 暴露所有自定义头
        response.setHeader("Access-Control-Max-Age", "3600"); // 预检请求缓存时间
        // 处理OPTIONS预检请求
        if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            log.info("OPTIONS预检请求,放行");
            filterChain.doFilter(request, response);
            return;
        }


        //1. 获取请求路径
        String requestURI = request.getRequestURI();

        //2. 判断是否包含login,register,包含说明是登录/注册操作,放行
        if (requestURI.contains("/login")|| requestURI.contains("/register")) {
            log.info("登录操作,放行");
            filterChain.doFilter(request, response); // 放行
            return;
        }

        //3.获取请求头中的token
        String token = request.getHeader("token");

        //4. 判断token是否存在,如果不存在,说明未登录,返回错误信息
        if(token == null||token.isEmpty()){
            log.info("令牌为空,未登录");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);// 401
            return;
        }

        //5.如果存在,校验令牌是否正确,正确放行,错误返回错误信息
        try {
            Claims claims = JwtUtils.parseToken(token);
            if("/batchInputScore".equals(requestURI)){
                //获取用户名
                String username = (String) claims.get("username");
                log.info("用户名：{}", username);
                ThreadLocalA.set(username);//放入线程本地变量,供同线程共享数据
            }
        } catch (Exception e) {
            log.info("令牌非法,响应401");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);// 401
            return;
        }

        //6.校验通过,放行
        log.info("令牌校验通过,放行");
        filterChain.doFilter(request, response); // 放行
        ThreadLocalA.remove();//移除线程本地变量

    }

}
